package com.example.config;

import java.util.concurrent.Executor;

import javax.validation.Validator;

import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.example.config.filter.HttpRequestFilter;
import com.example.config.resp.CustomObjectMapper;
import com.example.config.resp.RtnMsgUtil;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableWebMvc
@EnableScheduling
@EnableAsync
@EnableDiscoveryClient
@EnableOAuth2Sso
public class WebConfigurer extends WebMvcConfigurerAdapter{

	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
	
	@Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor processor =
                new MethodValidationPostProcessor();
        processor.setValidator(validator());
        return processor;
    }
     
    @Bean
    public Validator validator() {
        return new LocalValidatorFactoryBean();
    }
    
    @Bean("rtnMsgUtil")
    public RtnMsgUtil rtnMsgUtil(){
    	return new RtnMsgUtil();
    }
    
    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("PAY-");
        executor.initialize();
        return executor;
    }
    
    @Bean
    public MappingJackson2HttpMessageConverter httpMessageConverter(){
    	return new MappingJackson2HttpMessageConverter(objectMapper());
    }
    
    @Bean
    public ObjectMapper objectMapper(){
    	return new CustomObjectMapper();
    }
    
    @Bean
    public RequestContextListener requestContextListener() {
        return new RequestContextListener();
    }
    
    @Bean
    OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext, OAuth2ProtectedResourceDetails details) {
        return new OAuth2RestTemplate(details, oauth2ClientContext);
    }
    
    @Bean
	public FilterRegistrationBean myOncePerRequestFilterRegistration() {
		FilterRegistrationBean registration = new FilterRegistrationBean();
		registration.setFilter(new HttpRequestFilter() {
			@Override
			public boolean exclusive(String uri) {
				if (uri.startsWith("/static")) {
					return true;
				}
				return false;
			}
		});
		registration.addUrlPatterns("/*");// 拦截路径
		registration.setName("HttpRequestFilter");// 拦截器名称
		registration.setOrder(Ordered.HIGHEST_PRECEDENCE);// 顺序
		return registration;
	}
}

